package com.yjzx.util.service.aop.log;

import com.alibaba.fastjson.JSONObject;
import com.yjzx.util.common.util.StringUtils;
import com.yjzx.util.common.util.uuid.UUID;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author yjzx
 * @date 2024/7/9
 * @description 可多次重入，每次拥有唯一id的日志打印
 */
@Slf4j
@Aspect
@Component
public class LoggerAop extends OncePerRequestFilter implements Ordered {
    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        filterChain.doFilter(new ContentCachingRequestWrapper(request), response);
    }
    @Around("execution(public * com..service..*.*(..))")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {


        //切面中调切面方法提供支持
        String uuid = MDC.get("httpKey");
        if (StringUtils.isNotBlank(uuid)) {
            //存在唯一id，为重入日志打印
            int index = uuid.indexOf("-");
            if (index != -1) {
                int a = Integer.parseInt(uuid.substring(index + 1));
                uuid = uuid + "-" + (a + 1);
            } else {
                uuid = uuid + "-" + (1);
            }
        } else {
            uuid = UUID.randomUUID().toString(false);
        }
        MDC.put("httpKey", uuid);
        logStart();
        Object object;
        try {
            long start = System.currentTimeMillis();
            object = joinPoint.proceed();
            logEnd(start, object);
        } finally {
            String uuid1 = MDC.get("httpKey"), uuid2;
            if (uuid1 != null) {
                int index = uuid1.indexOf("-");
                if (index != -1) {
                    int a = Integer.parseInt(uuid.substring(index + 1));
                    if (a <= 1) {
                        uuid2 = uuid1.split("-")[0];
                    } else {
                        uuid2 = uuid1.split("-")[0] + "-" + (a - 1);
                    }
                    MDC.put("httpKey", uuid2);
                } else {
                    MDC.remove("httpKey");
                }

            }

        }
        return object;
    }

    private void logStart() {

    }

    private void logEnd(long start, Object result) {
        String maskedResult = result != null ? JSONObject.toJSONString(result) : "";
        log.info("{}ms,明文响应数据：{}", System.currentTimeMillis() - start, maskedResult);
    }

}
